Add support for RUSTDOCFLAGS
authorAlex Crichton <alex@alexcrichton.com>
Mon, 20 Jun 2016 16:12:28 +0000 (09:12 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 20 Jun 2016 16:12:28 +0000 (09:12 -0700)
Like with RUSTFLAGS, parse this variable to pass along extra arguments to
invocations of `rustdoc`.

src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/fingerprint.rs
src/cargo/ops/cargo_rustc/mod.rs
tests/rustdocflags.rs [new file with mode: 0644]

index bf458bcbf5c8113a7dda021843374aa2af2417c8..964450e98e0066549782a64f439046f47241de6f 100644 (file)
@@ -160,11 +160,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
                               crate_types: &BTreeSet<String>,
                               kind: Kind)
                               -> CargoResult<()> {
+        let rustflags = try!(env_args(self.config,
+                                      &self.build_config,
+                                      kind,
+                                      "RUSTFLAGS"));
         let mut process = util::process(self.config.rustc());
         process.arg("-")
                .arg("--crate-name").arg("_")
                .arg("--print=file-names")
-               .args(&try!(rustflags_args(self.config, &self.build_config, kind)))
+               .args(&rustflags)
                .env_remove("RUST_LOG");
 
         for crate_type in crate_types {
@@ -644,7 +648,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
     }
 
     pub fn rustflags_args(&self, unit: &Unit) -> CargoResult<Vec<String>> {
-        rustflags_args(self.config, &self.build_config, unit.kind)
+        env_args(self.config, &self.build_config, unit.kind, "RUSTFLAGS")
+    }
+
+    pub fn rustdocflags_args(&self, unit: &Unit) -> CargoResult<Vec<String>> {
+        env_args(self.config, &self.build_config, unit.kind, "RUSTDOCFLAGS")
     }
 
     pub fn show_warnings(&self, pkg: &PackageId) -> bool {
@@ -655,9 +663,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
 
 // Acquire extra flags to pass to the compiler from the
 // RUSTFLAGS environment variable and similar config values
-fn rustflags_args(config: &Config,
-                  build_config: &BuildConfig,
-                  kind: Kind) -> CargoResult<Vec<String>> {
+fn env_args(config: &Config,
+            build_config: &BuildConfig,
+            kind: Kind,
+            name: &str) -> CargoResult<Vec<String>> {
     // We *want* to apply RUSTFLAGS only to builds for the
     // requested target architecture, and not to things like build
     // scripts and plugins, which may be for an entirely different
@@ -688,7 +697,7 @@ fn rustflags_args(config: &Config,
     }
 
     // First try RUSTFLAGS from the environment
-    if let Some(a) = env::var("RUSTFLAGS").ok() {
+    if let Some(a) = env::var(name).ok() {
         let args = a.split(" ")
             .map(str::trim)
             .filter(|s| !s.is_empty())
@@ -697,7 +706,9 @@ fn rustflags_args(config: &Config,
     }
 
     // Then the build.rustflags value
-    if let Some(args) = try!(config.get_list("build.rustflags")) {
+    let name = name.chars().flat_map(|c| c.to_lowercase()).collect::<String>();
+    let key = format!("build.{}", name);
+    if let Some(args) = try!(config.get_list(&key)) {
         let args = args.val.into_iter().map(|a| a.0);
         return Ok(args.collect());
     }
index 437474c498e5ea28d0699769aacafb9458b87019..449e69667131e7ea71bc0b965bf6bf0cfc795a3a 100644 (file)
@@ -346,6 +346,11 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
     };
     let mut deps = deps;
     deps.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b));
+    let extra_flags = if unit.profile.doc {
+        try!(cx.rustdocflags_args(unit))
+    } else {
+        try!(cx.rustflags_args(unit))
+    };
     let fingerprint = Arc::new(Fingerprint {
         rustc: util::hash_u64(&cx.config.rustc_info().verbose_version),
         target: util::hash_u64(&unit.target),
@@ -354,7 +359,7 @@ fn calculate<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>)
         deps: deps,
         local: local,
         memoized_hash: Mutex::new(None),
-        rustflags: try!(cx.rustflags_args(unit)),
+        rustflags: extra_flags,
     });
     cx.fingerprints.insert(*unit, fingerprint.clone());
     Ok(fingerprint)
index 6b07d8f413f0bac2696c0af6e9a9a7d968b0beb0..ec1945803b625ec9479e0cb05cbb98642e86af94 100644 (file)
@@ -245,7 +245,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
     let dep_info_loc = fingerprint::dep_info_loc(cx, unit);
     let cwd = cx.config.cwd().to_path_buf();
 
-    let rustflags = try!(cx.rustflags_args(unit));
+    rustc.args(&try!(cx.rustflags_args(unit)));
 
     return Ok(Work::new(move |state| {
         // Only at runtime have we discovered what the extra -L and -l
@@ -269,9 +269,6 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
             }
         }
 
-        // Add the arguments from RUSTFLAGS
-        rustc.args(&rustflags);
-
         state.running(&rustc);
         try!(exec_engine.exec(rustc).chain_error(|| {
             human(format!("Could not compile `{}`.", name))
@@ -405,6 +402,8 @@ fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult<Work> {
                                   .build_out(unit.pkg));
     }
 
+    rustdoc.args(&try!(cx.rustdocflags_args(unit)));
+
     let name = unit.pkg.name().to_string();
     let build_state = cx.build_state.clone();
     let key = (unit.pkg.package_id().clone(), unit.kind);
diff --git a/tests/rustdocflags.rs b/tests/rustdocflags.rs
new file mode 100644 (file)
index 0000000..aa91471
--- /dev/null
@@ -0,0 +1,85 @@
+extern crate cargotest;
+extern crate hamcrest;
+
+use cargotest::support::{project, execs};
+use hamcrest::assert_that;
+
+#[test]
+fn parses_env() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/lib.rs", "");
+    p.build();
+
+    assert_that(p.cargo("doc").env("RUSTDOCFLAGS", "--cfg=foo").arg("-v"),
+                execs().with_status(0)
+                       .with_stderr_contains("\
+[RUNNING] `rustdoc [..] --cfg=foo[..]`
+"));
+}
+
+#[test]
+fn parses_config() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/lib.rs", "")
+        .file(".cargo/config", r#"
+            [build]
+            rustdocflags = ["--cfg", "foo"]
+        "#);
+    p.build();
+
+    assert_that(p.cargo("doc").arg("-v"),
+                execs().with_status(0)
+                       .with_stderr_contains("\
+[RUNNING] `rustdoc [..] --cfg foo[..]`
+"));
+}
+
+#[test]
+fn bad_flags() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/lib.rs", "");
+    p.build();
+
+    assert_that(p.cargo("doc").env("RUSTDOCFLAGS", "--bogus"),
+                execs().with_status(101));
+}
+
+#[test]
+fn rerun() {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/lib.rs", "");
+    p.build();
+
+    assert_that(p.cargo("doc").env("RUSTDOCFLAGS", "--cfg=foo"),
+                execs().with_status(0));
+    assert_that(p.cargo("doc").env("RUSTDOCFLAGS", "--cfg=foo"),
+                execs().with_status(0).with_stderr(""));
+    assert_that(p.cargo("doc").env("RUSTDOCFLAGS", "--cfg=bar"),
+                execs().with_status(0).with_stderr("\
+[DOCUMENTING] foo v0.0.1 ([..])
+"));
+}